<!DOCTYPE html>
<html lang="zh-cn">
  <head>
    <meta charset="UTF-8">
    <title>Sucha's Blog - Archive for February, 2020</title>
    <meta name="generator" content="MarkdownProjectCompositor.lua">
    <meta name="author" content="Sucha">
    <meta name="keywords" content="suchang, programming, Linux, Lua">
    <meta name="description" content="Sucha's blog">
    <link rel="shortcut icon" href="../images/ico.png">
    <link rel="stylesheet" type="text/css" href="../styles/blog.css">
    <link rel="stylesheet" type="text/css" href="../styles/prism.min.css">
    <style id="site_theme"></style>
  </head>
  <body>
    <div id="body">
      <div id="text">
	   <!-- Page published by cmark-gfm begins here --><h1>Sucha's Blog ~ Archive for February, 2020</h1>
<p><a id="p0"></a></p>
<div class="date">20年2月2日 周日 22:22</div>
<h2>mon_sched</h2>
<p>好早之前，为了检测自己写的一个程序是否仍然存活，以及使用的内存、CPU 占用情况，我用 Lua 加上系统的 top 命令，整了一个 <a href="https://github.com/lalawue/app_scheduler">app_scheduler</a>，将多个需要运行的程序做为一个进程组的概念组合起来，并用 Lua 的 os.execute() 实现切换工作目录，并将环境变量传递进去。</p>
<p>用 Lua 的好处是相当灵活，可以自定义任何时候，将程序拉起来，或者 kill 掉。但是缺点也很明显，这里周期性的用 top 命令，每次都得起一个 shell 进程，查看完信息后就退出了，有些浪费；而且要完成这样的一个控制结构，需要不少的 Lua 编程基础，还需要知道控制结构本身不同函数的作用才行。</p>
<p>后来看到了 <a href="https://github.com/tj/mon">mon</a>，一个程序的 supervisor，只管一个进程，控制结构是相当的简单。我之前关于进程组概念的想法又冒了出来，想着将其改写为管理进程组，并且用 JSON 做为配置工具，最好还有类似 cron 控制周期性运行的能力。</p>
<p>后来就自己验证了一下，发现其实是可以的，然后就产生了 <a href="https://github.com/lalawue/mon_sched">mon_sched</a>，一个进程组 supervisor。使用 JSON 的控制结构也相当的简单，而且部分功能沿用了 mon 本来的配置：</p>
<pre><code class="language-json">{
        &quot;name&quot; : &quot;mon_group&quot;,
        &quot;logfile&quot; : &quot;mon_sched.log&quot;,
        &quot;pidfile&quot; : &quot;mon_sched.pid&quot;,
        &quot;daemon&quot; : false,
        &quot;mon1&quot; : {
                &quot;logfile&quot;: &quot;log1.txt&quot;,
                &quot;cmd&quot;: &quot;example/program.sh&quot;,
                &quot;attempts&quot;: 20,
		        &quot;sleep&quot;: 10,
		        &quot;on_error&quot; : &quot;&quot;,
		        &quot;on_restart&quot; : &quot;&quot;,
                &quot;cron&quot;: &quot;* * * * 2&quot;
        },
        &quot;mon2&quot; : {
                &quot;cmd&quot;: &quot;example/program2.sh&quot;,
                &quot;logfile&quot;: &quot;log2.txt&quot;,——
                &quot;attempts&quot;: 30,
                &quot;sleep&quot;: 5,
                &quot;cron&quot;: &quot;1 * * * *&quot;
        }
}
</code></pre>
<p>上最外层的 name 是进程组的名称，日志、pid 文件路径，以及是否需要做为 daemon 运行；下面的是每个需要拉起程序的配置，cmd 是程序的路径以及参数，attempts 是重试次数，on_restart、on_error 是失败后重启、或者超过重试次数后的 shell 命令。</p>
<p>特别介绍一下 cron 参数，从左到右分别是分钟、小时，月日期、月份、周日期，并且支持部分域配置，比如</p>
<pre><code class="language-source">&quot;0,30,45   */3     2,[4-9]     *       *&quot;
# minius   hour    month_day   month   weak_day
# (0-59)   (0-23)  (1-31)      (0-11)  (0-6)
</code></pre>
<p>上面标示每个月的2号，以及4-9号，每3个小时的1、31、46分，运行一次程序。</p>
<p>话说为了实现这样的控制，存储结构用了 bitmap（还是觉得有些浪费），然后解析需要两层，第一层解析 blank、*、/、DIGIT 做为 TOKEN（其他可以认为是结束符，或者非法），然后比如 */3 这样的，需要保存上一个 TOKEN，用栈来实现，因为只有一层，其实用一个单独的变量比如 LAST_TOKEN 也是可以的；然后遇到空格、逗号、连字符后面的下一个数字 TOKEN，认为是一次识别结束，将位置相关的数字，设置到 bitmap 里面，话说重复的话也不管它了。</p>
<p>最后提一下，mon 本身就有说明不想用 awkward 的 DSL，然后参数都从命令行传递，而且为了保证稳定性，只管一个进程。相比之下，mon_sched 是都退回去了，用了 JSON 做为配置，然后管多个进程。</p>
<p>经验有限，更看中功能吧，也许是吃的苦还不够多。。。</p>
<div class="category"><a href="CategoryProgramming.html">CategoryProgramming</a> / <a href="2020-02.html#p0">Permalink</a> / <a href="https://github.com/lalawue/homepage/discussions/categories/blog" target="_blank">Discussion</a></div>
<!-- Page published by cmark-gfm ends here -->
  <div id="foot">2004-<script>var d = new
	Date();document.write(d.getFullYear())</script> &copy;
	Sucha. Powered by MarkdownProjectCompositor.
  </div>
  </div><!-- text -->
  <div id="sidebar">
  </div><!-- sidebar -->
  <script src="../js/prism.min.js" async="async"></script>
  <script src="../js/blog_sidebar.js"></script>
  </div> <!-- body -->
</body>
</html>